<?php
/**
 * Created by 无所谓已
 * SubtitleDetector.php
 * 字幕检测服务类
 * Time: 2025/01/27
 */

namespace app\service;

class SubtitleDetector
{
    /**
     * 检测视频字幕信息
     *
     * @param string $videoFile 视频文件路径
     * @return array 字幕信息数组
     */
    public function detectSubtitles($videoFile)
    {
        $result = [
            'has_subtitle' => false,
            'has_chinese_subtitle' => false,
            'subtitle_streams' => [],
            'external_subtitle' => null,
            'chinese_subtitle_stream' => null,
            'chinese_external_subtitle' => null
        ];

        if (!file_exists($videoFile)) {
            return $result;
        }

        // 检测内置字幕流
        $result['subtitle_streams'] = $this->detectSubtitleStreams($videoFile);
        if (!empty($result['subtitle_streams'])) {
            $result['has_subtitle'] = true;
            // 检查是否有中文字幕流
            foreach ($result['subtitle_streams'] as $stream) {
                if ($this->isChineseSubtitle($stream)) {
                    $result['has_chinese_subtitle'] = true;
                    $result['chinese_subtitle_stream'] = $stream;
                    break;
                }
            }
        }

        // 检测外部字幕文件
        $externalSubtitle = $this->findExternalSubtitle($videoFile);
        if ($externalSubtitle) {
            $result['has_subtitle'] = true;
            $result['external_subtitle'] = $externalSubtitle;
            // 检查外部字幕是否为中文
            if ($this->isChineseExternalSubtitle($externalSubtitle)) {
                $result['has_chinese_subtitle'] = true;
                $result['chinese_external_subtitle'] = $externalSubtitle;
            }
        }

        return $result;
    }

    /**
     * 检测视频内置字幕流
     *
     * @param string $videoFile 视频文件路径
     * @return array 字幕流信息数组
     */
    private function detectSubtitleStreams($videoFile)
    {
        $subtitleStreams = [];

        // 使用ffprobe检测字幕流
        $cmd = "ffprobe -v quiet -select_streams s -show_entries stream=index,codec_name,codec_type,tags:stream_tags=language,title -of json \"" . $videoFile . "\" 2>&1";
        
        exec($cmd, $output, $returnCode);
        
        if ($returnCode !== 0) {
            return $subtitleStreams;
        }

        $jsonOutput = implode("\n", $output);
        $data = json_decode($jsonOutput, true);

        if (isset($data['streams']) && is_array($data['streams'])) {
            foreach ($data['streams'] as $stream) {
                if (isset($stream['codec_type']) && $stream['codec_type'] === 'subtitle') {
                    $subtitleInfo = [
                        'index' => $stream['index'] ?? null,
                        'codec_name' => $stream['codec_name'] ?? '',
                        'language' => $stream['tags']['language'] ?? '',
                        'title' => $stream['tags']['title'] ?? ''
                    ];
                    $subtitleStreams[] = $subtitleInfo;
                }
            }
        }

        return $subtitleStreams;
    }

    /**
     * 判断是否为中文字幕
     *
     * @param array $subtitleInfo 字幕信息
     * @return bool
     */
    public function isChineseSubtitle($subtitleInfo)
    {
        if (!is_array($subtitleInfo)) {
            return false;
        }

        $language = strtolower($subtitleInfo['language'] ?? '');
        $title = strtolower($subtitleInfo['title'] ?? '');

        // 常见的中文语言代码
        $chineseCodes = ['chi', 'zh', 'zh-cn', 'zh-tw', 'zh-hans', 'zh-hant', 'chinese', 'cn'];
        
        // 检查语言代码
        foreach ($chineseCodes as $code) {
            if (strpos($language, $code) !== false) {
                return true;
            }
        }

        // 检查标题中的中文标识
        $chineseKeywords = ['chinese', '中文', '简体', '繁体', 'ch', 'cn'];
        foreach ($chineseKeywords as $keyword) {
            if (strpos($title, $keyword) !== false) {
                return true;
            }
        }

        return false;
    }

    /**
     * 查找外部字幕文件
     *
     * @param string $videoFile 视频文件路径
     * @return string|null 字幕文件路径，如果未找到返回null
     */
    private function findExternalSubtitle($videoFile)
    {
        $videoDir = dirname($videoFile);
        $videoName = pathinfo($videoFile, PATHINFO_FILENAME);
        $videoExtension = pathinfo($videoFile, PATHINFO_EXTENSION);

        // 常见的字幕文件扩展名
        $subtitleExtensions = ['srt', 'ass', 'ssa', 'vtt', 'sub', 'idx'];
        
        // 常见的中文字幕文件名模式
        $chinesePatterns = [
            'zh', 'zh-cn', 'zh-tw', 'chinese', 'cn', 'chs', 'cht', 
            '简体', '繁体', '中文', 'ch', 'sc', 'tc'
        ];

        // 优先查找中文字幕文件
        foreach ($chinesePatterns as $pattern) {
            foreach ($subtitleExtensions as $ext) {
                // 模式1: video.zh-cn.srt
                $subtitleFile = $videoDir . '/' . $videoName . '.' . $pattern . '.' . $ext;
                if (file_exists($subtitleFile)) {
                    return $subtitleFile;
                }
                // 模式2: video.zh-cn (无视频扩展名)
                $subtitleFile = $videoDir . '/' . $videoName . '.' . $pattern . '.' . $ext;
                if (file_exists($subtitleFile)) {
                    return $subtitleFile;
                }
            }
        }

        // 查找同名字幕文件（无语言标识）
        foreach ($subtitleExtensions as $ext) {
            $subtitleFile = $videoDir . '/' . $videoName . '.' . $ext;
            if (file_exists($subtitleFile)) {
                return $subtitleFile;
            }
        }

        // 查找视频文件名去掉扩展名后的字幕文件
        $baseName = str_replace('.' . $videoExtension, '', $videoName);
        foreach ($subtitleExtensions as $ext) {
            $subtitleFile = $videoDir . '/' . $baseName . '.' . $ext;
            if (file_exists($subtitleFile)) {
                return $subtitleFile;
            }
        }

        return null;
    }

    /**
     * 判断外部字幕文件是否为中文
     *
     * @param string $subtitleFile 字幕文件路径
     * @return bool
     */
    private function isChineseExternalSubtitle($subtitleFile)
    {
        $filename = basename($subtitleFile);
        $filenameLower = strtolower($filename);

        // 检查文件名中的中文标识
        $chinesePatterns = [
            'zh', 'zh-cn', 'zh-tw', 'chinese', 'cn', 'chs', 'cht',
            '简体', '繁体', '中文', 'ch', 'sc', 'tc'
        ];

        foreach ($chinesePatterns as $pattern) {
            if (strpos($filenameLower, $pattern) !== false) {
                return true;
            }
        }

        // 尝试读取字幕文件内容的前几KB来检测中文字符
        if (file_exists($subtitleFile) && filesize($subtitleFile) > 0) {
            $content = file_get_contents($subtitleFile, false, null, 0, 4096);
            if ($content !== false) {
                // 检测是否包含中文字符
                if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $content)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 获取最佳字幕信息（用于截图）
     *
     * @param array $subtitleInfo 字幕检测结果
     * @return array|null 最佳字幕信息，如果没有返回null
     */
    public function getBestSubtitleForScreenshot($subtitleInfo)
    {
        // 优先使用中文字幕
        if ($subtitleInfo['has_chinese_subtitle']) {
            // 优先使用外部中文字幕文件
            if ($subtitleInfo['chinese_external_subtitle']) {
                return [
                    'type' => 'external',
                    'file' => $subtitleInfo['chinese_external_subtitle']
                ];
            }
            // 其次使用内置中文字幕流
            if ($subtitleInfo['chinese_subtitle_stream']) {
                return [
                    'type' => 'internal',
                    'stream' => $subtitleInfo['chinese_subtitle_stream']
                ];
            }
        }

        // 如果没有中文字幕，使用第一个可用的字幕
        if (!empty($subtitleInfo['subtitle_streams'])) {
            return [
                'type' => 'internal',
                'stream' => $subtitleInfo['subtitle_streams'][0]
            ];
        }

        if ($subtitleInfo['external_subtitle']) {
            return [
                'type' => 'external',
                'file' => $subtitleInfo['external_subtitle']
            ];
        }

        return null;
    }
}

